package top.v5it.logback.push.convergence;

import lombok.Getter;
import lombok.Setter;

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 延迟收敛策略，首次不推送，首次后超过设置的超时间后，只后续发生马上推送一次，否则不推送
 *
 * @author zhanpu
 * @date 2022/9/9
 */
@Setter
@Getter
public class DelayConvergenceStrategy implements ConvergenceStrategy {

    private final static ConcurrentMap<String, Long> delay = new ConcurrentHashMap<>();

    /**
     * 超时时间，单位秒
     */
    private long timeout;

    /**
     * 按消息体中消息编号和当前时间记录，当单条消息到来前后达到{@link DelayConvergenceStrategy#timeout}限制就推送此条消息并删除超时时间
     *
     * @param payload 消息体
     * @return
     */
    @Override
    public boolean isPush(byte[] payload) {
        return getMsgId(payload).map(t -> {
            final long toEpochSecond = ConvergenceStrategy.toEpochSecond();
            // 首次不推送
            if (delay.putIfAbsent(t, toEpochSecond) == null) return false;
            final Long value = delay.computeIfPresent(t, (k, v) -> (v + timeout - toEpochSecond <= 0) ? null : toEpochSecond);
            return Objects.isNull(value);
        }).orElse(Boolean.FALSE);
    }
}
